package com.example.baweyplayer.activities;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.example.baweyplayer.R;
import com.example.baweyplayer.abstracts.AbstractFullscreenActivity;
import com.example.baweyplayer.internals.Song;
import com.example.baweyplayer.listeners.OnPlaybackEndListener;
import com.example.baweyplayer.runnables.ProgressBarUpdater;
import com.example.baweyplayer.singletons.Constants;
import com.example.baweyplayer.singletons.PlaybackQueue;

public class PlayerActivity extends AbstractFullscreenActivity {

	public static enum PlaybackMode {
		DEFAULT(0, R.string.mode_default), REPEAT_ONE(1,
				R.string.mode_repeat_one), REPEAT_ALL(2,
				R.string.mode_repeat_all);
		private int id;
		private int textId;

		private PlaybackMode(int modeId, int textId) {
			this.id = modeId;
			this.textId = textId;
		}

		public int getId() {
			return this.id;
		}

		public int getTextId() {
			return this.textId;
		}

		public static PlaybackMode getNext(PlaybackMode current) {
			int nextId = (current.getId() + 1) % PlaybackMode.values().length;
			for (PlaybackMode mode : PlaybackMode.values()) {
				if (mode.getId() == nextId) {
					return mode;
				}
			}
			return current;
		}

	}

	private MediaPlayer mp;
	private PlaybackQueue queue;
	private ProgressBarUpdater progressBarUpdater;
	private Handler progressBarHandler;

	private boolean shuffleEnabled = true;
	private int SENSITIVITY_THRESHOLD = 777;

	private PlaybackMode playbackMode = PlaybackMode.DEFAULT;

	public boolean isShuffleEnabled() {
		return shuffleEnabled;
	}

	public void setShuffleEnabled(boolean shuffleEnabled) {
		this.shuffleEnabled = shuffleEnabled;
	}

	public Handler getProgressBarHandler() {
		return progressBarHandler;
	}

	public MediaPlayer getMediaPlayer() {
		return mp;
	}

	public PlaybackQueue getPlaybackQueue() {
		return queue;
	}

	public ProgressBarUpdater getProgressBarUpdater() {
		return progressBarUpdater;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Log.v("baweyLog", "is logged");
		this.setContentView(R.layout.player_layout);
		progressBarHandler = new Handler();
		mp = new MediaPlayer();
		mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
		mp.setOnCompletionListener(new OnPlaybackEndListener(this));
		queue = PlaybackQueue.getInstance();
		// launch the progress bar updater, so that it reschedules itself
		progressBarUpdater = new ProgressBarUpdater(this);
		progressBarUpdater.run();
		// super
		super.onCreate(savedInstanceState);
		((Button) findViewById(R.id.button7)).setText(playbackMode.getTextId());
	}

	// mp.release(); on Paused // stoped

	public void playAudio(View view) {
		Log.d("baweyTest", "playAudio start");
		Log.d("baweyTest", "curPos fun: " + mp.getCurrentPosition());
		int currPos = Integer.valueOf(mp.getCurrentPosition()).intValue();
		Log.d("baweyTest", "currentPosition: " + currPos);
		if (currPos == 0) {
			Log.d("baweyTest", "currentPosition = 0");
		}
		if (currPos > 0) {
			Log.d("baweyTest", "currentPosition > 0");
		}
		if (currPos < 0) {
			Log.d("baweyTest", "currentPosition < 0");
		}

		mp.start();
		if (mp.isPlaying()) {
			return;
		} else {
			loadTrack(queue.getCurrentTrack(), true);
		}

	}

	public void loadTrack(Song song, boolean shouldStart) {
		if (song != null) {
			mp.reset();
			try {
				mp.setDataSource(song.getAbsolutePath());
				mp.prepare();
			} catch (Throwable th) {
				th.printStackTrace();
			}
			if (shouldStart) {
				mp.start();
			} else {
				progressBarUpdater.setNeedsUpdate(true);
			}
			Log.d("baweyTest", "position: " + mp.getCurrentPosition());
			Log.d("baweyTest", "started paudio playback");
		}
	}

	public void pauseAudio(View view) {
		Log.d("baweyTest", "pauseAudio call");
		mp.pause();
	}

	// called upon finishing a song playback
	public void followingTrack() {
		Log.d("baweyTest", "followingTrack call");
		Song nextTrack = null;
		switch (this.playbackMode) {
		case REPEAT_ONE:
			nextTrack = queue.getCurrentTrack();
			break;
		case REPEAT_ALL:
			nextTrack = queue.getNextTrack(true);
			break;
		default:
			nextTrack = queue.getNextTrack(false);
			break;
		}
		loadTrack(nextTrack, true);

	}

	public void nextTrack(View view) {
		Log.d("baweyTest", "nextTrack call");
		loadTrack(queue.getNextTrack(true), mp.isPlaying());
	}

	public void prevTrack(View view) {
		Log.d("baweyTest", "position: " + mp.getCurrentPosition());
		int position = mp.getCurrentPosition();
		Log.d("baweyTest", "int position: " + position);
		Song song = null;
		if (mp.getCurrentPosition() < SENSITIVITY_THRESHOLD) {
			Log.d("baweyTest", "switching to previous track");
			song = queue.getPreviousTrack(true);
		} else {
			Log.d("baweyTest", "rewinding track");
			song = queue.getCurrentTrack();
		}
		loadTrack(song, mp.isPlaying());
	}

	public void stopAudio(View view) {
		mp.reset();
	}

	/**
	 * A test-method to find all the tracks and put them in the playback queue
	 */
	public void enqueueAllTracks(View view) {
		File dir = new File(Constants.MUSIC_FOLDER);
		List<Song> audioFiles = getAllAudio(dir);
		Log.v("baweyTest", "Found " + audioFiles.size() + " audio files.");
		queue.enqueueAll(audioFiles);
	}

	private boolean isAudio(File file) {
		String[] tokens = file.getName().split("\\.");
		return tokens.length > 0
				&& tokens[tokens.length - 1].equalsIgnoreCase("mp3");
	}

	private List<Song> getAllAudio(File dir) {
		List<Song> files = new LinkedList<Song>();
		if (dir.isDirectory()) {
			for (String filename : dir.list()) {
				Song file = new Song(dir.getAbsolutePath() + File.separator
						+ filename);
				if (file.isDirectory()) {
					files.addAll(getAllAudio(file));
				} else {
					if (isAudio(file)) {
						files.add(file);
					}
				}
				Log.v("baweyTest", filename);
			}
		}
		return files;
	}

	public void switchPlaybackMode(View view) {
		Button button = (Button) view;
		playbackMode = PlaybackMode.getNext(playbackMode);
		button.setText(playbackMode.getTextId());
	}

}
